<?php
declare(strict_types=1);

namespace Zlf\Unit;

/**
 * 数组工具类
 * Class Arr
 * @package Zlf\Unit
 */
class Arr
{

    /**
     * 无限多维数组合并,在原有的基础上由右面的值合并前面的值
     * @param ...$arrays
     * @return array|mixed
     * @author 2021-06-01 22:47:58
     */
    public static function merge(...$arrays): array
    {
        $array = [];
        foreach ($arrays as $item) {
            if (!is_array($item)) return $item;
            foreach ($item as $key => $info) {
                if (is_array($info)) {
                    if (isset($array[$key]) && $array[$key]) {
                        $array[$key] = self::merge($array[$key], $info);
                        continue;
                    }
                }
                $array[$key] = $info;
            }
        }
        return $array;
    }


    /**
     * 获取数组父子数据结构
     * @param $array
     * @param string $findName
     * @param string $pid
     * @param string $child
     * @param int|string $root
     * @return array
     * @author 竹林风@875384189 2021/3/1 15:55
     */
    public static function getTree($array, string $findName = 'id', string $pid = 'pid', string $child = 'children', $root = 0): array
    {
        $tree = [];
        $packData = [];
        foreach ($array as $data) {
            $packData[$data[$findName]] = $data;
        }
        foreach ($packData as $key => $val) {
            if ($val[$pid] == $root) {
                $tree[] = &$packData[$key];
            } else {
                $packData[$val[$pid]][$child][] = &$packData[$key];
            }
        }
        return $tree;
    }


    /**
     * 数组MD5
     * @param array $array
     * @param bool $len_16
     * @return string
     */
    public static function md5(array $array, bool $len_16 = false): string
    {
        $json = http_build_query($array);
        return $len_16 ? substr(md5($json), 8, 16) : md5($json);
    }


    /**
     * 提取指定元素值为一个新的元素
     * @param $array
     * @param null $key
     * @return array
     * @author 竹林风@875384189 2021/3/11 16:44
     */
    public static function getValues($array, $key = null): array
    {
        $values = [];
        foreach ($array as $item) {
            if (is_null($key)) {
                $values[] = $item;
            } else {
                $values[] = $item[$key];
            }
        }
        return $values;
    }


    /**
     * 数组转键值对数据
     * @param $array
     * @param string $keyName
     * @param string $valName
     * @return array
     * @author 竹林风@875384189 2021/7/13 18:17
     */
    public static function map($array, string $keyName = 'id', string $valName = 'name'): array
    {
        $data = [];
        foreach ($array as $row) {
            $data[$row[$keyName]] = $row[$valName];
        }
        return $data;
    }


    /**
     * 重置一维数组键名为数组自然排序
     * @param array $array
     * @return array
     */
    public static function resetSort(array $array): array
    {
        $new = [];
        foreach ($array as $item) {
            $new[] = $item;
        }
        return $new;
    }


    /**
     * 深度获取数组数据
     * @param array $array
     * @param string $key
     * @param null $default
     * @return array|mixed|null
     */
    public static function get(array $array, string $key, $default = null)
    {
        $keys = Str::explode('.', trim($key));
        foreach ($keys as $k) {
            if (is_array($array) && isset($array[$k])) {
                $array = $array[$k];
            } else {
                return $default;
            }
        }
        return $array;
    }


    /**
     * 截取指定长度数组
     * @param array $array
     * @param int $start
     * @param int $count
     * @return array  返回的将是1维数组
     */
    public static function subArray(array $array, int $start, int $count): array
    {
        $arr = [];
        $index = 0;
        foreach ($array as $value) {
            if ($start >= $index) $arr[] = $value;
            if ($count === count($arr)) return $arr;
        }
        return $arr;
    }


    /**
     * 获取数组最后一个元素值
     * @param array $array
     * @return mixed|null
     */
    public static function finalValue(array $array)
    {
        $value = null;
        foreach ($array as $item) {
            $value = $item;
        }
        return $value;
    }


    /**
     * 获取第一个元素值
     * @param array $array
     * @return mixed|null
     */
    public static function firstValue(array $array)
    {
        foreach ($array as $item) {
            return $item;
        }
        return null;
    }


    /**
     * 获取数组最后一个键名称
     * @param array $array
     * @return int|string|null
     */
    public static function finalKey(array $array)
    {
        $keyName = null;
        foreach ($array as $key => $item) {
            $keyName = $key;
        }
        return $keyName;
    }


    /**
     * 获取数组第一个元素名
     * @param array $array
     * @return int|string|null
     */
    public static function firstKey(array $array)
    {
        foreach ($array as $key => $item) {
            return $key;
        }
        return null;
    }


    /**
     * 判断数组是列表还是字典
     * @param array $arr
     * @return string
     */
    public static function type(array $arr): string
    {
        return Is::list($arr) ? 'list' : 'map';
    }

    /**
     * 接收指定参数
     * @param array $array
     * @param array $keys
     * @return array
     */
    public static function receive(array $array, array $keys): array
    {
        $data = [];
        foreach ($keys as $item) {
            if (is_array($item)) {
                if (isset($array[$item[0]])) {
                    $data[$item[0]] = $array[$item[0]];
                } elseif (isset($item[1]) && !is_null($item[1])) {
                    $data[$item[0]] = $item[1];
                }
            } else {
                if (isset($array[$item])) {
                    $data[$item] = $array[$item];
                }
            }
        }
        return $data;
    }


    /**
     * 删除多维数组中的空元素
     * @author 竹林风@875384189 2022/6/2 9:51
     */
    public static function removeEmptyElements($arr)
    {
        foreach ($arr as $k => $v) {
            if (is_array($v) && count($v) > 0) {
                $arr[$k] = self::removeEmptyElements($v);
            }
            if (empty($v)) unset($arr[$k]);
        }
        return $arr;
    }
}

